package  cn.itcast.bos.utils;

import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/**
 * @author WBH 约定属性和Excel表格中的对应关系 。比如： Excel表格中 列数1,2,3分别对应
 *         {id,username,password} 本次工具类抽取没有进行类型判断
 *
 *         还有一种处理方式： 将Excel 每行记录的数据和Bean的属性名做个Map<String,String> map = new
 *         HashMap<BeanFieldName,cellValue>. 然后将map通过BeanUtils.populate()做数据封装
 *
 */
public class ExcelUtils {
    /**
     * @param path
     *            excel文件路径
     * @param clazz
     *            要封装的实体类Class对象
     * @param args
     *            字段名称
     */
    public static List importXls(File file,String fileName, Class clazz, String... args) {
        List<Object> list = new ArrayList<Object>();
        try {
            // 返回结果数据集合
            Sheet sheet = getExcelSheetByFile(file,fileName);
            for (Row row : sheet) {
                if (row.getRowNum() > 0) {
                    Object realObj = clazz.newInstance();
                    for (int i = 0; i < args.length; i++) {// 传入的参数列表进行遍历"id","username","gender"
                        // 读取Cell
                        Field field = clazz.getDeclaredField(args[i]);
                        field.setAccessible(true);
                        // field.getType();
                        Cell cell = row.getCell(i);// 得到当前行的第i+1个Cell
                        String cellValue = getCellStringValue(cell);// 此处将所有类型都转换成了字符串进行处理
                        field.set(realObj, cellValue);
                    }
                    list.add(realObj);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 获取表格内数据
     *
     * @param cell
     * @return
     */
    private static String getCellStringValue(Cell cell) {
        String cellValue;
        switch (cell.getCellType()) {
            case Cell.CELL_TYPE_NUMERIC: // 数字
                cellValue = (int) cell.getNumericCellValue() + "";
                break;

            case Cell.CELL_TYPE_STRING: // 字符串
                cellValue = cell.getStringCellValue();
                break;

            case Cell.CELL_TYPE_BOOLEAN: // Boolean
                cellValue = cell.getBooleanCellValue() + "";
                break;

            case Cell.CELL_TYPE_FORMULA: // 公式
                cellValue = cell.getCellFormula() + "";
                break;

            case Cell.CELL_TYPE_BLANK: // 空值
                cellValue = "";
                break;

            case Cell.CELL_TYPE_ERROR: // 故障
                cellValue = "非法字符";
                break;
            default:
                cellValue = "未知类型";
                break;
        }
        return cellValue;
    }

    /**
     * 根据不同的文件后缀名得到不同版本的Workbook对象,返回其sheet对象
     *
     * @param filePath
     * @return
     * @throws Exception
     */
    public static Sheet getExcelSheet(String filePath) throws Exception {
        // 1、加载Excel文件
        Workbook workbook = null;
        if (filePath.matches("^.+\\.(?i)(xls)$")) {
            workbook = new HSSFWorkbook(new FileInputStream(filePath));// xls后缀
        } else if (filePath.matches("^.+\\.(?i)(xlsx)$")) {
            workbook = new XSSFWorkbook(new FileInputStream(filePath));//
        }
        // 2、加载第一个sheet页
        Sheet sheet = workbook.getSheetAt(0);
        return sheet;
    }

    // 【我的补充】根据后缀名来确定excel的版本
    public static Sheet getExcelSheetByFile(File file, String fileName) {
        Workbook workbook = null;
        try {
            // 1、加载Excel文件

            // 表达式的结尾处的不区分大小写 i 标记指定不区分大小写。

            if (fileName.matches("^.+\\.(?i)(xls)$")) {
                workbook = new HSSFWorkbook(new FileInputStream(file));// xls后缀
            } else if (fileName.matches("^.+\\.(?i)(xlsx)$")) {
                workbook = new XSSFWorkbook(new FileInputStream(file));//
            }
            // 2、加载第一个sheet页
            Sheet sheet = workbook.getSheetAt(0);
            return sheet;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

